<?php
/**
 * File: User.php
 * User: Mr.Yang
 * Date: 2025/3/24 0024
 * Time: 14:31
 * Note:
 */

namespace app\home\controller;

use app\admin\model\Address;
use app\admin\model\OrderInfo;
use app\admin\model\User as UserModel;
use app\admin\model\Book as BookModel;
use app\admin\model\Borrow as BorrowModel;
use app\admin\model\Order as OrderModel;
use app\common\controller\Area;
use think\Db;

class User extends Base
{
    protected $model = null;
    protected $noCheck = ['User/login', 'User/logout', 'User/register', 'User/captcha'];
    protected $status_text = array(
        0 => array('text' => '待归还', 'color' => 'badge badge-primary'),
        1 => array('text' => '已逾期', 'color' => 'badge badge-danger'),
        2 => array('text' => '已归还', 'color' => 'badge badge-success')
    );

    public function initialize()
    {
        parent::initialize();
        if (!in_array($this->url, $this->noCheck)) {
            $this->checkLogin();
        }
        $this->model = new UserModel();
    }

    /**
     * Note: 个人中心
     * User: Mr.Yang
     * @return mixed
     */
    public function index()
    {
        $uid = session('userid');
        $user = UserModel::where('id', '=', $uid)->findOrFail();
        $this->assign('user', $user);
        return $this->fetch();
    }

    /**
     * Note: 我的订单
     * User: Mr.Yang
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function order()
    {
        $uid = session('userid');
        //获取订单列表
        $order = OrderModel::where('userid', '=', $uid)->order('id', 'desc')->selectOrFail();
        foreach ($order as $k => $v) {
            $info = OrderInfo::where('order_id', '=', $v['id'])->order('id', 'asc')->selectOrFail();
            $order[$k]['goods'] = $info;
        }
        $this->assign('order', $order);
        return $this->fetch();
    }

    /**
     * Note: 订单详情
     * User: Mr.Yang
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function orderinfo($id)
    {
        $order = OrderModel::where('id', '=', $id)->find();
        $orderInfo = OrderInfo::where('order_id', '=', $id)->select()->toArray();
        $this->assign('order', $order);
        $this->assign('orderinfo', $orderInfo);
        return $this->fetch();
    }

    /**
     * Note: 我的借阅
     * User: Mr.Yang
     * @return mixed
     */
    public function read()
    {
        //获取我借阅的书本
        $uid = session('userid');
        $book = BorrowModel::where('userid', '=', $uid)->alias('b')->field('b.*, k.bname, k.thumb')->leftJoin('book k', 'b.bookid=k.id')
            ->order('b.id', 'desc')->select();
        foreach ($book as $k => $v) {
            if ($v['status'] != 2){
                if ($v['back'] < date('Y-m-d')) {
                    $v['status'] = 1;
                }
            }
            $book[$k]['dstatus'] = $this->status_text[$v['status']];
            $book[$k]['status'] = $v['status'];
        }
        $this->assign('book', $book);
        return $this->fetch();
    }

    /**
     * Note: 归还借书
     * User: Mr.Yang
     */
    public function back()
    {
        if ($this->request->isAjax()) {
            $id = $this->request->get('id');
            $borrow = BorrowModel::where([['id', '=', $id], ['userid', '=', session('userid')]])->findOrFail();
            if ($borrow['status'] == 2) {
                $this->success('归还成功');
            }
            $flag = false;
            Db::startTrans();
            try{
                BorrowModel::where([['id', '=', $id], ['userid', '=', session('userid')]])->update([
                    'status' => 2,
                    'update_entered' => date('Y-m-d H:i:s')
                ]);
                BookModel::where('id', '=', $borrow['bookid'])->setInc('total');
                BookModel::where('id', '=', $borrow['bookid'])->setDec('number');
                Db::commit();
                $flag = true;
            }catch (\Exception $e) {
                Db::rollback();
            }
            if ($flag) {
                //设置
                $this->success('归还成功');
            }
            $this->error('归还失败');
        }
    }

    /**
     * Note: 删除借书记录
     * User: Mr.Yang
     * @throws \Exception
     */
    public function delborrow()
    {
        if ($this->request->isAjax()) {
            $id = $this->request->get('id');
            $res = BorrowModel::where([['id', '=', $id], ['userid', '=', session('userid')]])->delete();
            if ($res) {
                $this->success('删除成功');
            }
            $this->error('删除失败');
        }
    }

    /**
     * Note: 提交图书借阅
     * User: Mr.Yang
     */
    public function borrow()
    {
        if ($this->request->isAjax()) {
            $data = $this->request->post('data/a');
            $date = date('Y-m-d');
            $result = $this->validate($data, [
                'bookid' => 'require|number',
                'back' => 'require|after:'.$date
            ], [
                'bookid.require' => '图书不能为空',
                'back.require' => '归还日期不能为空',
                'back.after' => '归还日期要大于'.$date
            ]);
            if ($result !== true) {
                $this->error($result);
            }
            $userid = session('userid');
            $data['userid'] = $userid;
            //判断是否已经借过了
            $borrow_count = BorrowModel::where([['bookid', '=', $data['bookid']], ['userid', '=', $userid], ['status', 'neq', 2]])->count();
            if ($borrow_count>0) {
                $this->error('该图书已借阅，请先归还');
            }
            $flag = false;
            Db::startTrans();
            try{
                //修改图书库存
                BookModel::where('id', '=', $data['bookid'])->setInc('number', 1);
                BookModel::where('id', '=', $data['bookid'])->setDec('total', 1);
                //加入借阅表
                BorrowModel::create($data);
                Db::commit();
                $flag = true;
            }catch (\Exception $e) {
                Db::rollback();
            }
            if ($flag) {
                $this->success('借书成功');
            }
            $this->error('借书失败');
        }
    }

    /**
     * Note: 修改个人资料
     * User: Mr.Yang
     * @return mixed
     */
    public function edit()
    {
        $uid = session('userid');
        if ($this->request->isAjax()) {
            $data = $this->request->post('data/a');
            $password = $data['password'];
            if (!$password) {
                unset($data['password']);
            }
            $result = $this->validate($data, 'User.edit');
            if ($result !== true) {
                $this->error($result);
            }
            if ($password) {
                if (strlen($password) < 5) {
                    $this->error('密码不能少于5位');
                }
                $data['salt'] = createNonceStr(6);
                $data['password'] = createPassword($password, $data['salt']);
            }
            $data['update_entered'] = date('Y-m-d H:i:s');
            $res = UserModel::where('id', '=', $uid)->update($data);
            if ($res !== false) {
                $this->success('修改资料成功');
            }
            $this->error('修改资料失败');
        }
        $user = UserModel::where('id', '=', $uid)->findOrFail();
        $this->assign('user', $user);
        return $this->fetch();
    }

    /**
     * Note: 修改登录密码和支付密码
     * User: Mr.Yang
     * @return mixed
     */
    public function password()
    {
        if ($this->request->isAjax()) {
            $data = $this->request->post('data/a');
            $password = $data['password'];
            $payword = $data['payword'];
            $change = array();
            if ($password) {
                $result = $this->validate([
                    'password' => $password,
                    'rpassword' => $data['rpassword']
                ], [
                    'password' => 'require|min:5',
                    'rpassword' => 'require|confirm:password'
                ], [
                    'password.require' => '登录密码不能为空',
                    'password.min' => '登录密码不能少于5位',
                    'rpassword.require' => '登录密码不能为空',
                    'rpassword.confirm' => '两次登录密码不一致',
                ]);
                if ($result !== true) {
                    $this->error($result);
                }
                $change['salt'] = createNonceStr(6);
                $change['password'] = createPassword($password, $change['salt']);
            }
            if ($payword) {
                $result = $this->validate([
                    'payword' => $payword,
                    'rpayword' => $data['rpayword']
                ], [
                    'payword' => 'require|min:5',
                    'rpayword' => 'require|confirm:rpayword'
                ], [
                    'payword.require' => '支付密码不能为空',
                    'payword.min' => '支付密码不能少于5位',
                    'rpayword.require' => '支付密码不能为空',
                    'rpayword.confirm' => '两次支付密码不一致',
                ]);
                if ($result !== true) {
                    $this->error($result);
                }
                $change['paysalt'] = createNonceStr(6);
                $change['payword'] = createPassword($payword, $change['paysalt']);
            }
            if ($change) {
                $uid = session('userid');
                $change['update_entered'] = date('Y-m-d H:i:s');
                UserModel::where('id', '=', $uid)->update($change);
            }
            $this->success('修改密码成功');
        }
        return $this->fetch();
    }

    /**
     * Note: 我的收货地址
     * User: Mr.Yang
     * @return mixed
     */
    public function address()
    {
        $uid = session('userid');
        $address = Address::where('userid', '=', $uid)->order('is_default', 'desc')->select();
        $this->assign('address', $address);
        return $this->fetch();
    }

    /**
     * Note: 添加、编辑我的收货地址
     * User: Mr.Yang
     * @return mixed
     */
    public function myaddress()
    {
        if ($this->request->isAjax()) {
            $id = $this->request->post('id', 0);
            $data = $this->request->post('data/a');
            $result = $this->validate($data, 'Address');
            if ($result !== true) {
                $this->error($result);
            }
            $uid = session('userid');
            $addressModel = new Address();
            if ($id) {
                $msg = '编辑';
                $res = $addressModel->edit($id, $data);
            }else{
                $data['userid'] = $uid;
                $res = $addressModel->add($data);
                $msg = '添加';
            }
            if ($res) {
                $this->success($msg.'成功');
            }
            $this->error($msg.'失败');
        }

        $id = $this->request->get('id', 0);
        $province = Area::getAreaByPid(0);
        $html = '<select id="province" class="form-control"><option value="0">请选择</option>';
        if ($id) {
            $address = Address::where('id', '=', $id)->field('id, truename, mobile, address, areaid')->findOrFail();
            $area = $this->getAreaById($address['areaid']);
            foreach ($province as $k => $v) {
                $selected = '';
                if ($v['areaid'] == $area['parentid']) {
                    $selected = 'selected';
                }
                $html .= '<option value="'.$v['areaid'].'" '.$selected.'>'.$v['areaname'].'</option>';
            }
            $html .= '</select>';
            $city = Area::getAreaByPid($area['parentid']);
            $html .= '<select id="city" class="form-control" name="data[areaid]"><option value="0">请选择</option>';
            foreach ($city as $k => $v) {
                $selected = '';
                if ($v['areaid'] == $address['areaid']) {
                    $selected = 'selected';
                }
                $html .= '<option value="'.$v['areaid'].'" '.$selected.'>'.$v['areaname'].'</option>';
            }
            $html .= '</select>';
        }else{
            $address = array(
                'id' => 0,
                'truename' => '',
                'address' => '',
                'areaid' => '',
                'mobile' => '',
            );
            foreach ($province as $k => $v) {
                $html .= '<option value="'.$v['areaid'].'">'.$v['areaname'].'</option>';
            }
            $html .= '</select>';
        }

        $this->assign('address', $address);
        $this->assign('html', $html);
        $this->assign('id', $id);
        return $this->fetch();
    }

    /**
     * Note: 删除我的收货地址
     * User: Mr.Yang
     * @throws \Exception
     */
    public function deladdress()
    {
        if ($this->request->isAjax()) {
            $id = $this->request->get('id');
            $res = Address::where('id', '=', $id)->delete();
            if ($res) {
                $this->success('删除成功');
            }
            $this->error('删除失败');
        }
    }

    /**
     * Note: 设置默认地址
     * User: Mr.Yang
     */
    public function setdefault()
    {
        if ($this->request->isAjax()) {
            $id = $this->request->get('id');
            $uid = session('userid');
            Address::where('userid', '=', $uid)->update(['is_default' => 0]);
            $res = Address::where('id', '=', $id)->update(['is_default' => 1]);
            if ($res) {
                $this->success('设置默认地址成功');
            }
            $this->error('设置默认地址失败');
        }
    }

    /**
     * Note: 登录
     * User: Mr.Yang
     * @return mixed
     */
    public function login()
    {
        if ($this->request->isAjax()) {
            $data = $this->request->post('data/a');
            $result = $this->validate($data, [
                'username' => 'require',
                'password' => 'require',
                'captcha' => 'require'
            ], [
                'username.require' => '账号不能为空',
                'password.require' => '密码不能为空',
                'captcha.require' => '验证码不能为空'
            ]);
            if ($result !== true) {
                $this->error($result);
            }
            if (strtolower($data['captcha']) != session('code')) {
                $this->error('验证码错误');
            }
            $where = [['username', '=', $data['username']], ['mobile', '=', $data['username']]];
            $user = $this->model->getOneByWhere($where);
            if (empty($user)) {
                $this->error('用户不存在');
            }
            if (createPassword($data['password'], $user['salt']) != $user['password']) {
                $this->error('用户或密码错误');
            }
            session('userid', $user['id']);
            UserModel::where('id', '=', $user['id'])
                ->update(['last_login_time' => $user['login_time'], 'login_time' => date('Y-m-d H:i:s')]);
            $forward = cookie('forward');
            $this->success('登录成功', $forward ? $forward : '');
        }
        if (!$this->hasInCheck()) {
            $referer = $this->request->header('referer');
            cookie('forward', $referer);
        }
        return $this->fetch();
    }

    /**
     * Note: 是否需要检查
     * User: Mr.Yang
     * @return bool
     */
    private function hasInCheck()
    {
        $flag = false;
        $referer = $this->request->header('referer');
        foreach ($this->noCheck as $k => $v) {
            if (strpos($referer, strtolower($v))) {
                $flag = true;
                break;
            }
        }
        return $flag;
    }

    /**
     * Note: 注册
     * User: Mr.Yang
     * @return mixed
     */
    public function register()
    {
        if ($this->request->isAjax()) {
            $data = $this->request->post('data/a');
            $result = $this->validate($data, 'User.register');
            if ($result !== true) {
                $this->error($result);
            }
            $salt = createNonceStr(6);
            $password = createPassword($data['password'], $salt);
            unset($data['rpassword']);
            $data['password'] = $password;
            $data['salt'] = $salt;
            $res = $this->model->add($data);
            if ($res !== false) {
                $this->success('注册成功');
            }
            $this->error('注册失败');
        }
        return $this->fetch();
    }

    /**
     * Note: 退出登录
     * User: Mr.Yang
     */
    public function logout()
    {
        session('userid', null);
        $this->redirect(url('User/login'));
    }

    /**
     * Note: 验证码图片
     * User: Mr.Yang
     */
    public function captcha()
    {
        $captcha = new \Captcha();
        $content = $captcha->createImage();
        $code = $captcha->getCode();
        session('code', $code);
        header('content-type: image/png');
        echo $content;
    }
}